home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / applic / ntp / kent.shar / slowdes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-29  |  6.9 KB  |  305 lines

  1. /* slowdes.c --
  2.    this file contains a C-based DES algorithm implementation; the
  3.    version is modeled after the MBB implementation for
  4.    instructive clarity, and is not the most efficient version
  5.    available for the C/70.  It reads its key schedule and certain
  6.    tables from files generated by associated programs ksbuild.c
  7.    and tblbuild.c.  John Linn -- 4 March 1983 */
  8.    
  9. #include <stdio.h>
  10.  
  11. /* data structures to be read from files */
  12. static long ip [2] [256];     
  13. static long ipi [2] [256];
  14. static int ipis [8];
  15. static long snop [8] [64];
  16. unsigned ks [16] [4];
  17.  
  18. /* rdfiles -- reads filed info, returns 1 iff success, 0 otherwise */
  19. int rdfiles ()
  20. {
  21.   int i, j;
  22.   FILE *fp, *fopen ();
  23.  
  24.   if (NULL == (fp = fopen ("ip", "r")))
  25.   {
  26.     printf ("dodes -- can't read file 'ip'\n");
  27.     return (0);
  28.   }
  29.   for (i = 0; i < 2; i++)
  30.     for (j = 0; j < 256; j++) 
  31.       if (EOF == fscanf (fp, "%lx", &ip [i] [j]))
  32.       {
  33.         printf ("dodes -- 'ip' read failed at i=%d, j=%d\n", i, j);
  34.     return (0);
  35.       }
  36.   fclose (fp);
  37.   
  38.   if (NULL == (fp = fopen ("ipi", "r")))
  39.   {
  40.     printf ("dodes -- can't read file 'ipi'\n");
  41.     return (0);
  42.   }
  43.   for (i = 0; i < 2; i++)
  44.     for (j = 0; j < 256; j++) 
  45.       if (EOF == fscanf (fp, "%lx", &ipi [i] [j]))
  46.       {
  47.     printf ("dodes -- 'ipi' read failed at i=%d, j=%d\n", i, j);
  48.     return (0);
  49.       }
  50.   fclose (fp);
  51.   
  52.   if (NULL == (fp = fopen ("ipis", "r")))
  53.   {
  54.     printf ("dodes -- can't read file 'ipis'\n");
  55.     return (0);
  56.   }
  57.   for (i = 0; i < 8; i++) 
  58.     if (EOF == fscanf (fp, "%x", &ipis [i]))
  59.     {
  60.       printf ("dodes -- 'ipis' read failed at i=%d\n");
  61.       return (0);
  62.     }     
  63.   fclose (fp);
  64.   
  65.   if (NULL == (fp = fopen ("snop", "r")))
  66.   {
  67.     printf ("dodes -- can't read file 'snop'\n");
  68.     return (0);
  69.   }
  70.   for (i = 0; i < 8; i++)
  71.     for (j = 0; j < 64; j++) 
  72.       if (EOF == fscanf (fp, "%lx", &snop [i] [j]))
  73.       {
  74.         printf ("dodes -- 'snop' read failed at i=%d, j=%d\n", i, j);
  75.     return (0);
  76.       }
  77.   fclose (fp);
  78.  
  79.   if (NULL == (fp = fopen ("ks", "r")))
  80.   {
  81.     printf ("dodes -- can't read file 'ks'\n");
  82.     return (0);
  83.   }
  84.   for (i = 0; i < 16; i++)
  85.     for (j = 0; j < 4; j++) 
  86.       if (EOF == fscanf (fp, "%x", &ks [i] [j]))
  87.       {
  88.     printf ("dodes -- 'ks' read failed at i=%d, j=%d\n", i, j);
  89.     return (0);
  90.       }
  91.   fclose (fp);
  92.   
  93.   return (1);   /* success */
  94. }
  95.  
  96. /* 
  97.  
  98. eexpand -- this routine performs a version of the DES E
  99. transform, per Kent's algorithm for the MBB.  It accepts an input
  100. long and returns its result in 4 words of an unsigned array,
  101. ordered (1 3) (5 7) (2 4) (6 8).  Significant bits are left
  102. justified in 8-bit bytes in these words:  the two low order bits
  103. will always be zeroes.  This version is coded for clarity of
  104. correspondence to the C/30 MBB version, not taking much advantage
  105. of 32-bit operations.
  106.  
  107. */
  108.  
  109. #define MASK    0XFCFC;
  110.  
  111. eexpand (inlong, outarr)
  112. long            inlong;
  113. unsigned        outarr [];
  114. {
  115.   unsigned rega, regb, regc, regd;
  116.   int oddbith, oddbitl, i;
  117.  
  118.   rega = regc = (unsigned) (0XFFFFL & (inlong >> 16));  /* high bits */
  119.   regb = regd = (unsigned) (0XFFFFL & inlong);          /* low bits */
  120.  
  121.   /* rotate regc-regd pair right one */
  122.   oddbith = !! (regc & 01);
  123.   oddbitl = !! (regd & 01);
  124.   regc >>= 1;
  125.   regd >>= 1;
  126.   if (oddbitl) regc |= 0X8000;
  127.   if (oddbith) regd |= 0X8000;
  128.  
  129.   /* kill unused bits */
  130.   regc &= MASK;
  131.   regd &= MASK;
  132.  
  133.   /* rotate rega-regb pair left by three */
  134.   for (i = 0; i < 3; i++)
  135.   {
  136.     oddbith = !! (rega & 0X8000);
  137.     oddbitl = !! (regb & 0X8000);
  138.     rega <<= 1;
  139.     regb <<= 1;
  140.     if (oddbitl) rega |= 01;
  141.     if (oddbith) regb |= 01;
  142.   }
  143.  
  144.   /* kill unused bits */
  145.   rega &= MASK;
  146.   regb &= MASK;
  147.  
  148.   outarr [0] = regc;
  149.   outarr [1] = regd;
  150.   outarr [2] = rega;
  151.   outarr [3] = regb;
  152. }
  153.  
  154. #define BINBLK  8       /* number of bytes in an encryption chunk */
  155. #define BINLNG  4       /* the number of bytes in 32 bits of a long */
  156.  
  157. /* doip -- use ip table to permute 64 bits from inar to outar */
  158. doip (inar, outar)      
  159. long    inar [2];
  160. long    outar [2];
  161. {
  162.   extern long ip [2] [256];
  163.  
  164.   int i,j;
  165.  
  166.   outar [0] = outar [1] = 0L;
  167.  
  168.   for (i = 0; i < BINBLK; i++)  /* input is 8 bytes */
  169.                 /* msb of inar [0] ... lsb of inar [1] */
  170.   {
  171.     for (j = 0; j < 2; j++)     /* scan from r -> l */
  172.       outar [j] |= ip [j] [0XFF & ((i < BINLNG) ?
  173.             ((int) ((inar [1] >> (i * 8)))) :
  174.             ((int) ((inar [0] >> ((i - BINLNG) * 8)))) )];
  175.  
  176.     if (i == (BINBLK - 1)) break;     /* don't shift an extra time */
  177.  
  178.     for (j = 0; j < 2; j++) outar [j] <<= 1;
  179.   }
  180. }
  181.  
  182. /* doipi -- use ipi, ipis to perform ip-inverse */
  183. doipi (inar, outar)     
  184. long    inar [2];
  185. long    outar [2];
  186. {
  187.   extern int ipis [8];
  188.   extern long ipi [2] [256];
  189.  
  190.   int i, j, bp;
  191.  
  192.   outar [0] = outar [1] = 0L;
  193.  
  194.   for (i = 0; i < BINBLK; i++)  /* input is 8 bytes */
  195.   {
  196.     bp = ipis [i] - 1;  /* translate byte indexes to zero origin */
  197.  
  198.     for (j = 0; j < 2; j++)
  199.       outar [j] |= ipi [j] [0XFF & ((bp < BINLNG) ?
  200.             ((int) (inar [0] >> (((BINLNG - bp) - 1) * 8))) :
  201.             ((int) (inar [1] >> (((BINLNG - (bp-4)) - 1) * 8))) )];
  202.  
  203.     if (i == (BINBLK - 1)) break;
  204.  
  205.     for (j = 0; j < 2; j++) outar [j] <<= 1;
  206.   }
  207. }
  208.  
  209. /* des_encrypt -- encrypt a block under key sched in ks */
  210. des_encrypt (inar, outar)   
  211. long    inar [2];
  212. long    outar [2];
  213. {
  214.   extern unsigned ks [16] [4];
  215.   extern long snop [8] [64];
  216.  
  217.   int round, i, j;
  218.   unsigned expan [4];   /* receives output of E transform */
  219.   long sbout, scopy;
  220.   long oarr [2];
  221.  
  222.   doip (inar, outar);
  223.  
  224.   for (round = 0; round < 16; round++)
  225.   {
  226.     sbout = 0L;
  227.  
  228.     eexpand (outar [1], expan);
  229.  
  230.     for (i = 0; i < 4; i++)
  231.     { 
  232.       expan [i] ^= ks [round] [i];
  233.  
  234.       for (j = 0; j < 2; j++)
  235.       {
  236.         sbout |= snop [(i*2)+j] 
  237.          [0X3F & (j ? (expan [i] >> 2) : (expan [i] >> 10))];
  238.       }
  239.     }
  240.  
  241.     scopy = outar [0];
  242.     outar [0] = outar [1];
  243.     outar [1] = scopy ^ sbout;
  244.   }
  245.  
  246.   /* a final swap */
  247.   scopy = outar [0];
  248.   outar [0] = outar [1];
  249.   outar [1] = scopy;
  250.  
  251.   doipi (outar, oarr);  /* perform ip-inverse into temp copy */
  252.   outar [0] = oarr [0];
  253.   outar [1] = oarr [1];
  254. }
  255.  
  256. /* des_decrypt -- decrypt a block under key sched in ks */
  257. des_decrypt (inar, outar)   
  258. long    inar [2];
  259. long    outar [2];
  260. {
  261.   extern unsigned ks [16] [4];
  262.   extern long snop [8] [64];
  263.  
  264.   int round, i, j;
  265.   unsigned expan [4];   /* receives output of E transform */
  266.   long sbout, scopy;
  267.   long oarr [2];
  268.  
  269.   doip (inar, outar);
  270.  
  271.   for (round = 15; round >= 0; round--)
  272.   /* to do a DES decrypt, use key schedule in reverse order */
  273.   {
  274.     sbout = 0L;
  275.  
  276.     eexpand (outar [1], expan);
  277.  
  278.     for (i = 0; i < 4; i++)
  279.     { 
  280.       expan [i] ^= ks [round] [i];
  281.  
  282.       for (j = 0; j < 2; j++)
  283.       {
  284.         sbout |= snop [(i*2)+j] 
  285.          [0X3F & (j ? (expan [i] >> 2) : (expan [i] >> 10))];
  286.       }
  287.     }
  288.  
  289.     scopy = outar [0];
  290.     outar [0] = outar [1];
  291.     outar [1] = scopy ^ sbout;
  292.   }
  293.  
  294.   /* a final swap */
  295.   scopy = outar [0];
  296.   outar [0] = outar [1];
  297.   outar [1] = scopy;
  298.  
  299.   doipi (outar, oarr);  /* perform ip-inverse into temp copy */
  300.   outar [0] = oarr [0];
  301.   outar [1] = oarr [1];
  302. }
  303.  
  304.  
  305.